/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controladoras.negocio;
import interfaces.IPersistencia;
import interfaces.IGerenciaAeroporto;
import entidades.Aeroporto;
import java.util.ArrayList;
import entidades.Cidade;
import erros.ErroAtualizacao;
import erros.ErroCadastramento;
import erros.ErroPersistencia;
import erros.ErroRecuperacao;
import erros.ErroRemocao;
import comandos.Up.CmdUpAeroporto;
import comandos.CmdBD;
import comandos.Del.CmdDelAeroporto;
import comandos.Del.CmdDelVooHasAeroporto;
import comandos.Ins.CmdInsAeroporto;
import comandos.Sel.CmdSelAllAeroporto;
import comandos.Sel.CmdSelCidade;
import comandos.Up.CmdUpVooHasAeroporto;

/**
 * Controladora de negócio, implementa as regras de negócio
 * e a funcionalidade do sistema da entidade aeroporto.
 * @author daniel
 */
public class CntrGerenciaAeroporto implements IGerenciaAeroporto {
    /**
     * Referência para o singleton da classe controladora do aeroporto
     * na camada de de negócio.
     */
    private static CntrGerenciaAeroporto ref;
    /**
     * Controladora de persistência associada com essa controladora.
     */
    private IPersistencia cntrPersistencia;

    /**
     * Instancia o singleton da controladora de negócio da entidade aeroporto,
     * isto é, se ele não foi instanciado, cria o objeto, caso
     * contrário apenas retorna a referência para o mesmo. Desta forma apenas
     * uma instância do objeto está em execução.
     * @return Retorna a referência para o singleton.
     */
    public static CntrGerenciaAeroporto instanciar() {
        if (ref == null) {
            ref = new CntrGerenciaAeroporto();
        }
        return (ref);
    }
    /**
     * Seta a controladora de persistência
     * associada a controladora.
     * @param cntr Controladora de persistência à ser
     * associada à controladora.
     */
    public final void setCntrPersistencia(final IPersistencia cntr) {
        cntrPersistencia = cntr;
    }

    /**
     * Recupera os aeroportos no banco de dados.
     * @return Retorna a lista de aeroportos recuperados.
     * @throws ErroRecuperacao Lança a exceção de recuperação
     * em caso de falha.
     */
    @Override
    public ArrayList recuperarAeroportos() throws ErroRecuperacao {
        try {
            CmdBD comando = new CmdSelAllAeroporto();
            return (ArrayList) cntrPersistencia.executar(comando);
        } catch (ErroPersistencia e) {
            throw new ErroRecuperacao("Não foi possível recuperar os " +
                    "aeroportos");
        }
    }
    /**
     * Cadastra o aeroporto em uma cidade já existente.
     * @param aeroporto Aeroporto à ser cadastrado
     * @param cidade Cidade hospedeira do novo aeroporto.
     * @throws ErroCadastramento Lança exceção de
     * cadastramento em caso de falha.
     */
    @Override
    public void cadastrarAeroporto(Aeroporto aeroporto, Cidade cidade)
            throws ErroCadastramento {
        /**
         * verifica se a cidade está presente no banco
         */
        try{
            CmdBD comando = new CmdSelCidade(cidade);
            cntrPersistencia.executar(comando);
        } catch (ErroPersistencia e){
            throw new ErroCadastramento("Aeroporto não pode ser cadastrado" +
                    " em uma cidade inexistente");
        }

        /**
         * cadastra o aeroporto de fato
         **/
        try {
            CmdBD comando = new CmdInsAeroporto(aeroporto,cidade);
            cntrPersistencia.executar(comando);
         } catch (ErroPersistencia e) {
            throw new ErroCadastramento("Não foi possível" +
                    " cadastrar o aeroporto");
         }
    }
    /**
     * Deleta o aeroporto do banco de dados.
     * @param aeroporto Aeroporto à ser deletado.
     * @throws ErroRemocao
     */
    @Override
    public void deletarAeroporto(Aeroporto aeroporto) throws ErroRemocao {
        try {
            CmdBD comando = new CmdDelAeroporto(aeroporto);
            cntrPersistencia.executar(comando);
            comando = new CmdDelVooHasAeroporto(aeroporto);
        } catch (ErroPersistencia e) {
            throw new ErroRemocao("Falha na remoção do aeroporto");
        }

    }
    /**
     * Atualiza um aeroporto no banco de dados.
     * @param aeroportoVelho Aeroporto à ser atualizado.
     * @param aeroportoNovo Aeroporto com os dados novos.
     * @throws ErroAtualizacao Lança a exceção de atualização
     * em caso de falha.
     */
    @Override
    public void atualizarAeroporto(Aeroporto aeroportoVelho
            ,Aeroporto aeroportoNovo) throws ErroAtualizacao {
        /**
         * atualiza o aeroporto
         */
        try {
            CmdBD comando = new CmdUpAeroporto(aeroportoVelho,aeroportoNovo);
            cntrPersistencia.executar(comando);
            comando = new CmdUpVooHasAeroporto(aeroportoVelho,aeroportoNovo);
        } catch (ErroPersistencia e) {
            throw new ErroAtualizacao("Erro na atualização do aeroporto");
        }
    }

}
